#include"lkstack.h"

/*
InitStack:初始化一个空栈,分配一个栈
返回值:返回一个初始化好的栈的地址
*/
LKstack *InitStack()
{
    //给头结点分配空间并且初始化
    LKstack *s = (LKstack *)malloc(sizeof(LKstack));
    s->first = s->last = NULL;
    s->num = 0;
    return s;
}


/*
DestoryStack:销毁一个栈
@s:指向你要销毁的栈
返回值:无
*/
void DestoryStack(LKstack *s)
{
    ClearStack(s);
    free(s);
}


/*
ClearStack:清空一个栈(删除所有的数据节点)
@s:指向你要清空的栈
返回值:无
*/
void ClearStack(LKstack *s)
{
    while( !StackIsEmpty(s) )
    {
        Pop(s);
    }
}


/*
StackIsEmpty:判断栈是否为空(是否存在用户数据)
@s:指向你要操作的栈
返回值:
    如果栈为空,返回真  true 
    如果栈为非空,返回假  false
*/
bool StackIsEmpty(LKstack *s)
{
    return s==NULL || s->num == 0;
}


/*
StackSize:获取栈的大小(用户元素的个数)
@s:指向你要操作的栈
返回值:栈中的元素个数
*/
int StackSize(LKstack *s)
{
    return s==NULL? 0:s->num;   
}


/*
GetTop:获取栈顶元素,但是不出栈
@s:指向你要操作的栈
@v:指向一个可用的空间,用来保存获取到的栈顶元素
返回值:表示获取成功或者失败
    返回 true  表示成功
    返回 false 表示失败
*/
bool GetTop(LKstack *s,Elemtype *v)
{
    if(s == NULL || StackIsEmpty(s))
    {
        return false;  //获取失败
    }
    *v = s->last->data;   //栈顶元素的数据
    return true;
}


/*
Push:入栈,把一个用户数据存放到栈中去
@s:指向你要操作的栈
@e:你要入栈的元素
返回值:表示入栈成功或者失败
    返回 true  表示成功
    返回 false 表示失败
*/
bool Push(LKstack *s,Elemtype e)
{
    //把自己的数据放到链表中去
    if(s == NULL)
    {
        return false;
    }
    //先为元素e创建一个节点空间
    Node *p = (Node *)malloc(sizeof(Node));
    p->data = e;
    p->next = p->prev = NULL;
    //把元素加入到链表(尾部就是栈顶,使用尾插法)
    if(s->first == NULL)
    {
        s->first = s->last = p;
        s->num++;
    }else 
    {
        s->last->next = p;
        p->prev = s->last;
        s->last = p;
        s->num++;
    }
    return true;
}


/*
Pop:出栈,把一个用户数据从栈中拿出来
@s:指向你要操作的栈
返回值:表示出栈成功或者失败
    返回 true  表示成功
    返回 false 表示失败
*/
bool Pop(LKstack *s)
{
    if(s==NULL || StackIsEmpty(s))
    {
        return false;
    }
    //把栈顶元素干掉
    Node *p = s->last;
    if(s->first == s->last)  //栈中只有一个节点
    {
        free(p);
        s->first = s->last = NULL;
        s->num = 0;
    }else 
    {
        s->last = p->prev;
        p->prev = NULL;
        s->last->next = NULL;
        free(p);
        s->num--;
    }
    return true;
}


